<?php

namespace app\xcxapi\controller\v1;

use app\common\controller\XcxController;
use app\lib\exception\BaseException;
use app\models\AuthModel;
use app\models\CampusModel;
use app\models\MemberModel;
use app\models\MpModel;
use app\models\UserModel;
use think\Cache;
use think\Config;

class Register extends XcxController
{
    /**
     * 登陆接口
     * User: wufeng
     * Date: 2019/5/10.
     */
    public function login()
    {
        $param = input('post.');
        $rule = [
            'mobile' => 'require|number',
            'password' => 'require|length:6,16',
            'code' => 'require',
        ];
        $message = [
            'mobile.require' => '用户名不能为空',
            'mobile.number' => '用户名只能数字',
            'password.require' => '密码不能为空',
            'password.length' => '密码长度不正确',
            'code.require' => 'code不能为空',
        ];
        $result = $this->validate($param, $rule, $message);
        if (true !== $result) {
            $this->fail('PARAM_ERROR');
        }

        $memberModel = new MemberModel();
        $member = $memberModel->get(['mobile' => $param['mobile']]);
        if (null === $member) {
            $this->fail('USERNAME_NOT_EXIST');
        }
        $this->cachePrefix = 'EDU_TOKEN:'.$member['type'].':'.$this->token;
        $encodePassword = self::encodePassword($param['password'], $member['salt']);
        if ($member['password'] !== $encodePassword) {
            $cacheKey = $this->cachePrefix.'login_error_times_'.$param['mobile'];
            if (Cache::has($cacheKey)) {
                if (Cache::get($cacheKey) >= Config::get('max_login_error_times')) {
                    $this->fail('EXCEED_MAX_ERROR_LOGIN_TIMES');
                }
                Cache::inc($cacheKey);
            } else {
                Cache::set($cacheKey, 1, strtotime(date('Y-m-d').' 23:59:59') - time());
            }
            $this->fail('PASSWORD_NOT_RIGHT');
        }

        if (0 === (int) $member['status']) {
            $this->fail('USER_RESTRICT_LOGIN');
        }

        //更新最后登录状态
        $memberModel::update([
            'last_login_time' => $this->request->time(),
            'last_login_ip' => $this->request->ip(),
            'last_login_ip' => $this->request->ip(),
        ], ['member_id' => $member['member_id']]);

        $user = (new UserModel())->get($member['user_id']);
        $where = [];
        $where['id'] = ['in', $user['campus_id']];
        $campus = (new CampusModel())->where($where)->field('id,campus_name')->select()->toArray();

        $wtype_name = (new AuthModel())->get($user['group_id'])['title'];

        $this->handle($param['code'], $member['member_id'], $param['mp_id']);

        // 登入成功 先写基本session cookie
        $sessionData = [
            'user_id' => $member['user_id'],
            'name' => $user['name'],
            'img' => $user['img'],
            'company_id' => $member['company_id'],
            'mobile' => $member['mobile'],
            'auth_rules' => explode(',', $member['auth_rules']),
            'type' => $member['type'],
            'wtype' => $user['wtype'],
            'wtype_name' => $wtype_name,
            'campus_id' => $user['campus_id'],
            'campus' => $campus,
        ];

        $expireTime = Config::get('login_validity_time') ?: 86400;
        Cache::set($this->cachePrefix, $sessionData, $expireTime);

        $this->win('登录成功', ['userInfo' => $sessionData, 'token' => $this->token]);
    }

    /**
     * 修改密码
     * User: wufeng
     * Date: 2020/03/08.
     */
    public function changePassword()
    {
        $params = input('post.');
        $member = (new MemberModel())->get(['user_id' => xcxapi_get_current_user_id()]);
        $encodePassword = self::encodePassword($params['password'], $member['salt']);
        if ($member['password'] !== $encodePassword) {
            $this->fail('PASSWORD_NOT_RIGHT');
        }

        if ($params['password'] === $params['one_password']) {
            $this->fail('PASSWORD_CAN_NOT_ALIKE');
        }
        if ($params['one_password'] !== $params['two_password']) {
            $this->fail('PASSWORD_NOT_ALIKE');
        }
        $data['salt'] = md5(date('Y-m-d H:i:s'));
        $data['password'] = self::encodePassword($params['one_password'], $data['salt']);
        (new MemberModel())->save($data, ['user_id' => xcxapi_get_current_user_id()]);
        $this->win('修改成功');
    }

    /**
     * 功能:对用户输入的明文密码进行加密(还记不记得csdn的杯具).
     *
     * @param string $password 明文密码
     * @param string $salt     混淆字符串（盐）,防止简单的MD5加密被逆向破解
     *
     * @return string 加密后的密码
     */
    public static function encodePassword($password, $salt)
    {
        $encryptd_password = md5(md5($password).$salt);

        return substr($encryptd_password, 0, 32);
    }

    /**
     * 初始化.
     */
    protected function _initialize()
    {
        parent::_initialize(); // TODO: Change the autogenerated stub
        if (!$this->token) {
            $this->token = xcxapi_generate_token();
        }
    }

	/**
	 * User: wufeng
	 * Date: 2020/04/15
	 *
	 * @param $code
	 * @param $member_id
	 * @param $mp_id
	 * @throws BaseException
	 * @throws \think\exception\DbException
	 */
    private function handle($code, $member_id, $mp_id)
    {
        $mp = (new MpModel())->get($mp_id);
		$wxAppID = $mp['fw_appid'];
		$wxAppSecret = $mp['fw_secret'];
        $wxLoginUrl = sprintf(
            config('login_url'),
            $wxAppID,
            $wxAppSecret,
            $code
        );
        $result = curl_get($wxLoginUrl);
        $wxResult = json_decode($result, true);
        if (empty($wxResult)) {
			$this->fail('WECHAT_INTERNAL_ERROR');
        }
        $loginFail = \array_key_exists('errcode', $wxResult);
        if ($loginFail) {
            throw new BaseException($wxResult['errmsg'], $wxResult['errcode']);
        }

        (new MemberModel())->save(['openid' => $wxResult['openid']], ['member_id' => $member_id]);
    }
}
